<?php
// application/lib/ActionAbstract.php
/**
 * demo-zf application
 *
 * lib\Lib_ActionAbstract
 *
 * @author Adam Pilacki <adam.pilacki@gmail.com>
 */
abstract class Lib_ActionAbstract
    extends Zend_Controller_Action
{
    /**
     * All protected properties are set in _init<resource> methods
     */

    /**
     * @var Bootstrap
     */
    protected $_bootstrap = null;

    /**
     * @var Zend_Session_Namespace
     */
    protected $_sessionNamespace = null;

    /**
     * All app settings after merge
     *
     * @var Zend_Config_Ini
     */
    protected $_config = null;

    /**
     * @var boolean
     */
    protected $_isAuthenticated = false;

    /**
     * called before every action
     * overwrite it in controllers if necessary
     */
    public function init()
    {
        /* Log execution time to firebug */
        AdamP_Debug_Firebug::logCurrentExecutionTime('Lib_ActionAbstract::init() - start');

        /* @var $bootstrap Bootstrap */
        $this->_bootstrap = $this->getInvokeArg('bootstrap');
//        $this->_bootstrap->unregisterPluginResource('sessionNamespace');

        /* store request params in registry */
        Zend_Registry::set('moduleName', $this->getRequest()->getModuleName());

        /**
         * IMPORTANT pls do not change initialization\bootstraping order
         */

        /**
         * set up final global configuration
         *
         * overwrite it in controllers if necessary
         */
        $this->_initFinalConfig();

        /**
         * init db configuration - not create connections yet - lazy load
         *
         * db configuration must be initiated before session because
         * session will be saved to db (for server clusters)
         *
         * overwrite it in controllers if necessary
         */
        $this->_initDb();

        /**
         * set up session
         *
         * overwrite it in controllers if necessary
         */
        $this->_initSession();

        /**
         * set up auth storage and check authentication
         *
         * auth namespace is taken from config
         * resources.sessionNamespace.authNamespace
         *
         * overwrite it in controllers if necessary
         */
        $this->_initAuth();

        /**
         * resolve location before view\layout\translate\acl initiation
         * overwrite it in controllers if necessary
         */
        $this->_resolveLocation();

        /**
         * translate bootstrap
         * overwrite it in controllers if necessary
         */
        $this->_initTranslator();

        /**
         * view botstrap and initial properties
         * ovewrite it in controllers if necessary
         */
        $this->_initView();

        /**
         * layout botstrap and initial properties
         * ovewrite it in controllers if necessary
         */
        $this->_initLayout();
        /**
         * TODO PUT HERE CODE FOR:
         *    acl
         *    resolve cache
         */

        /* Log execution time to firebug */
        AdamP_Debug_Firebug::logCurrentExecutionTime('Lib_ActionAbstract::init() - end');
    }

    /**
     * Init final configuration
     * After execute this metod $this->_config is set
     *
     * Overwrite it in controllers if necessary
     */
    protected function _initFinalConfig()
    {
        $this->_bootstrap->bootstrapFinalConfig();
        $this->_config = $this->_bootstrap->getResource('finalConfig');
    }

    /**
     * Init db configuration(s)
     *
     * Overwrite it in controllers if necessary
     */
    protected function _initDb()
    {
        $this->_bootstrap->bootstrapDb();
    }

    /**
     * Init session
     * After execute this metod $this->_sessionNamespace is set
     *
     * Overwrite it in controllers if necessary
     */
    protected function _initSession()
    {
        $this->_bootstrap->bootstrapSession();
        $this->_bootstrap->bootstrapSessionNamespace();
        $this->_sessionNamespace = $this->_bootstrap->getResource('sessionNamespace');

        if (!isset($this->_sessionNamespace->lastPage)) {
            $this->_sessionNamespace->lastPage = '/';
        }
    }

    /**
     * Init auth storage and check authentication
     * After execute this metod $this->_isAuthenticated is set
     *
     * Overwrite it in controllers if necessary
     */
    protected function _initAuth()
    {
        $authNamespace = $this->_config->resources->sessionNamespace->authNamespace;
        Zend_Auth::getInstance()->setStorage(
            new Zend_Auth_Storage_Session(empty($authNamespace) ? Zend_Auth_Storage_Session::NAMESPACE_DEFAULT : $authNamespace)
        );
        $this->_isAuthenticated = $this->_isAuthenticated();
    }

    /**
     * Resolve location - called before view|layout initiation
     * Overwrite it in controllers if necessary
     */
    protected function _resolveLocation()
    {
    }

    /**
     * Init translator
     *
     * Overwrite it in controllers if necessary
     */
    protected function _initTranslator()
    {
        $this->_bootstrap->bootstrapTranslate();

        /**
         * Temporary moved to each controller individual - will see if it is good idea...
         */
//        $this->_translator = $this->_bootstrap->getResource('Translate');
    }

    /**
     * Initiate view
     * - bootstrap view
     * - bootstrap navigation
     * - set view basic settiongs dependent on auth
     * - set flash messages
     *
     * Overwrite it in controllers if necessary
     */
    protected function _initView()
    {
        $this->_bootstrap->bootstrapView();
        $this->view->lang = $this->_sessionNamespace->lang;
        $this->view->headMeta()
            ->appendHttpEquiv('Content-Language', str_replace('_', '-', str_replace('_', '-', $this->_sessionNamespace->lang)))
            ->appendName('keywords', '')
            ->appendName('description', '');

        /* boostrap navigation */
        $this->_bootstrap->bootstrapNavigation();

        /* auth view poperties */
        if ($this->_isAuthenticated) {
            $this->view->isAuthenticated = true;
            $this->view->authUserData = $this->_sessionNamespace->authUserData;
        } else {
            $this->view->isAuthenticated = false;
            $this->view->authUserData = array();
            /* set up login box */
            $this->view->loginForm = new Form_UserLogin();
        }

        /* set flash messages */
        /* @var $messenger Zend_Controller_Action_Helper_FlashMessenger */
        $messenger = $this->_helper->flashMessenger;
        $this->view->flashMessages = array(
            'success' => $messenger->setNamespace('success')->getMessages(),
            'warning' => $messenger->setNamespace('warning')->getMessages(),
            'error' => $messenger->setNamespace('error')->getMessages(),
        );
    }

    /**
     * Initiate layout settings
     * Overwrite it in controllers if necessary
     */
    protected function _initLayout()
    {
        $this->_bootstrap->bootstrapLayout();
        $this->view->layout = Zend_Layout::getMvcInstance()->getLayout();
    }

    /**
     * Returns true if user is authenticated
     *
     * Overwrite it in controllers if necessary
     *
     * @return boolean
     */
    protected function _isAuthenticated()
    {
        $auth = Zend_Auth::getInstance();

        if (!$auth->hasIdentity()) {
            return false;
        }

        return $auth->getIdentity() === Lib_AuthAdapter::IDENTITY_SUCCESS;
    }
}